<template>
  <Overlay
    :show="show"
    :overlay="overlay"
    :overlayClass="overlayClass"
    :closeOnClickOverlay="closeOnClickOverlay"
    @update:show="updateShow"
  />

  <transition :name="transitionName" mode="out-in">
    <template v-if="visible">
      <view
        v-show="show"
        :class="['lxd-popup', `lxd-popup--${position || 'center'}`, { 'lxd-popup--round': round }]"
        v-bind="attrs"
      >
        <view class="lxd-popup__closeable" v-if="closeable" @click.stop="changeShow">X</view>
        <slot>
          <view>{{ transitionName }}</view>
        </slot>
      </view>
    </template>
  </transition>
</template>

<script setup lang="ts">
import Overlay from "../Overlay/index.vue";
import { ref, watch, computed, useAttrs } from "vue";
import { onHide } from "@dcloudio/uni-app";

interface Props {
  show: boolean;
  overlay?: boolean;
  position?: string;
  overlayClass?: string;
  round?: boolean;
  closeable?: boolean;
  closeOnClickOverlay?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  show: false, // 是否显示弹出层
  overlay: true, // 是否显示遮罩层
  position: "", // 弹出位置，可选值为 top bottom right left
  overlayClass: "", // 自定义遮罩层类名
  round: false, // 是否显示圆角
  closeable: false, // 是否显示关闭按钮
  closeOnClickOverlay: true // 是否在点击遮罩层后关闭
});

const attrs = useAttrs(); // 获取所有非 props 的属性

const emits = defineEmits(["update:show"]);

const visible = ref(false);

const oneWacth = watch(
  () => props.show,
  (s) => {
    s && (visible.value = true);

    oneWacth();
  }
);

const transitionName = computed(() => {
  switch (props.position) {
    case "top":
      return "slide-top";
    case "bottom":
      return "slide-bottom";
    case "right":
      return "slide-right";
    case "left":
      return "slide-left";
    default:
      return "fade";
  }
});

const changeShow = () => {
  emits("update:show", false);
};

const updateShow = (value: boolean) => {
  emits("update:show", value);
};

onHide(() => {
  changeShow();
});
</script>

<style lang="scss">
.lxd-popup {
  position: fixed;
  z-index: 1997;
  max-height: 100vh;
  overflow-y: auto;
  background: #fff;
  transition: transform 0.3s;
}

.lxd-popup--round {
  border-radius: 20rpx;
}

.lxd-popup--center {
  width: 80%;
  background-color: #fff;
  top: 50%;
  left: 50%;
  transform: translate3d(-50%, -50%, 0);
}

.lxd-popup--top {
  width: 100%;
  min-height: 30%;
  top: 0;
  left: 0;
  border-radius: 0 0 20rpx 20rpx;
}

.lxd-popup--bottom {
  width: 100%;
  min-height: 30%;
  bottom: 0;
  left: 0;
  border-radius: 20rpx 20rpx 0 0;
}

.lxd-popup--right {
  width: 30%;
  min-height: 100%;
  top: 0;
  right: 0;
  border-radius: 20rpx 0 0 20rpx;
}

.lxd-popup--left {
  width: 30%;
  min-height: 100%;
  top: 0;
  left: 0;
  border-radius: 0 20rpx 20rpx 0;
}

.lxd-popup__closeable {
  position: absolute;
  top: 32rpx;
  right: 32rpx;
  color: #c8c9cc;
  font-size: 48rpx;
  line-height: 1;
}

.slide-top-enter-active,
.slide-top-leave-active,
.slide-bottom-enter-active,
.slide-bottom-leave-active,
.slide-right-enter-active,
.slide-right-leave-active,
.slide-left-enter-active,
.slide-left-leave-active {
  transition: all 0.3s ease;
}

.slide-top-enter-from,
.slide-top-leave-to {
  transform: translateY(-100%);
}

.slide-bottom-enter-from,
.slide-bottom-leave-to {
  transform: translateY(100%);
}

.slide-right-enter-from,
.slide-right-leave-to {
  transform: translate(100%, 0);
}

.slide-left-enter-from,
.slide-left-leave-to {
  transform: translateX(-100%);
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
